package impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import contraintes.*;
import fr.irit.smac.may.lib.components.messaging.receiver.AgentRef;
import fr.irit.smac.may.lib.interfaces.Push;
import interfaces.ILoad;
import interfaces.ISave;
import interfaces.agenttCreation.ILinkRefId;
import mysticedt.Database;

public class DatabaseImpl extends Database {
	//BDD Locale
	//Liste des etudiants avec la liste des ue ou ils sont inscrit
	private Hashtable<Integer,ArrayList<Integer>> listEtudiant = new Hashtable<Integer,ArrayList<Integer>>();
	//Liste des enseignants avec la liste des seances qu'ils dispensent
	private Hashtable<Integer,ArrayList<Integer>> listEnseignantSeance = new Hashtable<Integer,ArrayList<Integer>>();
	//Liste des enseignants avec leurs contraintes de dispo
	private Hashtable<Integer,ArrayList<ContrainteDispo>> listEnseignantDispo = new Hashtable<Integer,ArrayList<ContrainteDispo>>();
	//Liste des UE et de leur seance
	private Hashtable<Integer,ConstanteUE> listConstanteUE = new Hashtable<Integer,ConstanteUE>();
	//Lien entre AgentRef et Etudiant ou Enseignant
	private Hashtable<AgentRef,Integer> link = new Hashtable<AgentRef,Integer>();
	private Hashtable<Integer,AgentRef> linkInverse = new Hashtable<Integer,AgentRef>();
	
	@Override
	protected ISave save() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected ILoad pull() {
		// TODO Auto-generated method stub
		return new ILoad() {	
			public ArrayList<ContrainteDispo> getContraintesDispo(AgentRef a) {
				return listEnseignantDispo.get(link.get(a));
			}

			public ArrayList<Seance> getListIdCoursEns(AgentRef a) {
				ArrayList<Seance> res = new ArrayList<Seance>();
				Iterator<Integer> iteIdS = listEnseignantSeance.get(link.get(a)).iterator();
				while(iteIdS.hasNext()) {
					int ids = iteIdS.next();
					Iterator<ConstanteUE> iteCUE = listConstanteUE.values().iterator();
					while(iteCUE.hasNext()) {
						Seance s = iteCUE.next().getSeance(ids);
						if(s!=null)
							res.add(s);
					}
					
				}
				return res;
			}

			public ArrayList<Seance> getListIdCoursEtu(AgentRef a) {
				ArrayList<Seance> res = new ArrayList<Seance>();
				
				// ici il y a un risque de bug si link.get(a) return null;
				Iterator<Integer> iteIdUe = listEtudiant.get(link.get(a)).iterator();
				while(iteIdUe.hasNext()) {
					Iterator<Seance> iteIdS = listConstanteUE.get(iteIdUe.next()).getListSeance().iterator();
					while(iteIdS.hasNext()) {
						Seance s = iteIdS.next();
						s.setEnseignant(linkInverse.get(s.getIdEnseignant()));
						res.add(s);
					}
				}
				return res;
			}

			public ArrayList<Integer> getStudentList() {
				return new ArrayList<Integer>(listEtudiant.keySet());
			}

			public ArrayList<Integer> getTeacherList() {
				return new ArrayList<Integer>(listEnseignantSeance.keySet());
			}
		};
	}

	@SuppressWarnings("deprecation")
	private void scenario0() {
		//creation de deux enseignants et de deux etudiants
		int e1 = 0, etu1 = 1, etu2 = 2, e2 = 3;
		//Creation de deux seances, un cours et un TP
		Seance s1 = new Seance(0, e1, -1, 120, 30, TypeCours.COURS, false);
		Seance s2 = new Seance(1, e1, -1, 120, 20, TypeCours.TP, false);
		Seance s3 = new Seance(2, e2, -1, 120, 20, TypeCours.COURS, false);
		
		//Creation d'une UE composee d'un cours et d'un TP
		ConstanteUE c1 = new ConstanteUE(0, 1, 0, 1);
		c1.ajoutSeance(s1);
		c1.ajoutSeance(s2);
		listConstanteUE.put(c1.getId(), c1);
		//Creation d'une UE composee d'un cours
		ConstanteUE c2 = new ConstanteUE(2, 1, 0, 0);
		c2.ajoutSeance(s3);
		listConstanteUE.put(c2.getId(), c2);
		
		//l'enseignant e1 dispense un cours et un TP
		listEnseignantSeance.put(e1, new ArrayList<Integer>());
		listEnseignantSeance.get(e1).add(s1.getId());
		listEnseignantSeance.get(e1).add(s2.getId());
		listEnseignantDispo.put(e1, new ArrayList<ContrainteDispo>());
		listEnseignantDispo.get(e1).add(new ContrainteDispo(0, new Date(2012, 01, 01, 8, 00), new Date(2012, 01, 01, 12, 00)));
		//l'enseignant e2 dispense un cours
		listEnseignantSeance.put(e2, new ArrayList<Integer>());
		listEnseignantSeance.get(e2).add(s3.getId());
		listEnseignantDispo.put(e2, new ArrayList<ContrainteDispo>());
		listEnseignantDispo.get(e2).add(new ContrainteDispo(0, new Date(2012, 01, 01, 10, 00), new Date(2012, 01, 01, 16, 00)));
		
		//les deux etudiants sont inscrits a la meme UE
		listEtudiant.put(etu1, new ArrayList<Integer>());
		listEtudiant.get(etu1).add(c1.getId());
		listEtudiant.put(etu2, new ArrayList<Integer>());
		listEtudiant.get(etu2).add(c1.getId());
		listEtudiant.get(etu2).add(c2.getId());
	}

	@Override
	protected Push<String> initSenario() {
		return new Push<String>() {

			public void push(String thing) {
				// TODO ici to map la string avec la méthode 
				scenario0();
			}
			
			
		};
	}

	@Override
	protected ILinkRefId saveLinkAgentId() {
		// TODO Auto-generated method stub
		return new ILinkRefId() {
			
			public void saveLinkAgentId(AgentRef r, int i) {
				link.put(r, i);
				linkInverse.put(i,r);
			}
		};
	}
}
